#include <stdio.h>
#include <stdlib.h>
#include <csp_spu.h>
#include <csp_debug.h>

#include "../alting_test.h"


#define CHANNEL_NAME 42


int global_pid; 


int Run(){

	int pid = csp_pid();

	global_pid = csp_pid();

	int n_inputs = 5;

	int a2o_n   __attribute__ ((aligned(16)));
	int o2o_1_n __attribute__ ((aligned(16))); 
	int o2o_2_n __attribute__ ((aligned(16))); 
	int o2o_3_n __attribute__ ((aligned(16))); 
	int o2o_4_n __attribute__ ((aligned(16)));


	/*
	   printf("a2o_n=%p, o2o_1_n=%p, o2o_2_n=%p, o2o_3_n=%p, o2o_4_n=%p\n", 
	   &a2o_n  , &o2o_1_n, &o2o_2_n, &o2o_3_n, &o2o_4_n );
	   */


	csp_channel a2o;
	csp_channel o2o1, o2o2, o2o3, o2o4;


	a2o  = csp_create_channel(ANY2ONE_CHANNEL, A2O_CHANNEL, sizeof(int));
	o2o1 = csp_create_channel(ONE2ONE_CHANNEL, O2O_1_CHANNEL, sizeof(int));
	o2o2 = csp_create_channel(ONE2ONE_CHANNEL, O2O_2_CHANNEL, sizeof(int));
	o2o3 = csp_create_channel(ONE2ONE_CHANNEL, O2O_3_CHANNEL, sizeof(int));
	o2o4 = csp_create_channel(ONE2ONE_CHANNEL, O2O_4_CHANNEL, sizeof(int));


	csp_channel channels[] = { o2o4, o2o3, o2o2, o2o1, a2o };


	void *inputs[] = { &o2o_4_n, &o2o_3_n, &o2o_2_n, &o2o_1_n, &a2o_n }; 


	csp_guard_list guards = csp_create_guards(channels, n_inputs);


	ASSERT( A2O_VALUE   != a2o_n   );
	ASSERT( O2O_1_VALUE != o2o_1_n );
	ASSERT( O2O_2_VALUE != o2o_2_n );
	ASSERT( O2O_3_VALUE != o2o_3_n );
	ASSERT( O2O_4_VALUE != o2o_4_n );

	int n_msg = 9; int i=0;
	printf("Alting process has pid=%i.\n", pid);
	printf("Alting process expetcs to read %i messages.\n", n_msg);

	while( i < n_msg ){
		switch( csp_alt_select(guards, inputs, n_inputs) ){
			case 0:
				printf("0: o2o_4\n");
				ASSERT( O2O_4_VALUE == o2o_4_n );
				i++;
				break;
			case 1:
				printf("1: o2o_3\n");
				ASSERT( O2O_3_VALUE == o2o_3_n );
				i++;
				break;
			case 2:
				printf("2: o2o_2\n");
				ASSERT( O2O_2_VALUE == o2o_2_n );
				i++;
				break;
			case 3:
				printf("3: o2o_3\n");
				ASSERT( O2O_1_VALUE == o2o_1_n );
				i++;
				break;
			case 4:
				printf("4: a2o\n");
				ASSERT( A2O_VALUE == a2o_n );
				i++;
				break;
			default:
				printf("Error.\n");
				ASSERT( 0 );
				break;
		}
	}

	printf("Alting process (pid=%i) poison all channels.\n"
		   "After reading %i messages.\n", 
			csp_pid(), n_msg);


	ASSERT( 9 == i );

	ASSERT( pid == csp_pid() );
	ASSERT( global_pid == csp_pid() );

	PRINTF_FOR_TESTING("%s terminating on spe #%i with pid %i\n",__FILE__ , csp_spe_id(), pid);

	PRINTF_FOR_TESTING("Nested task with pid=%i terminated with res=%i.\n", pid, res);

	printf("der!\n");

	return 0;
}
